﻿using GJB.Models;
using System.Reflection;

namespace ReflectionDemo
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello, World!");


            //查看元数据
            ItemInfo itemInfo = new ItemInfo()
            {
                Id = 101,
                ItemType = "收入",
                ItemName = "银行转账",
                remark = "转账金额为1000元"
            };
            //第一步 得到type对象
            Type type = typeof(ItemInfo);
            
            //1.属性
            PropertyInfo[] properties = type.GetProperties();//所有的公开的属性数组
            foreach (PropertyInfo property in properties)
            {
                Console.WriteLine(property.Name + ":" + property.GetValue(itemInfo).ToString());
                //property.Name获取属性的名称，property.GetValue(obj)获取obj对象中property属性的值
            }

            //获取ItemType的属性值
            PropertyInfo itemTyoeProperty = type.GetProperty("ItemType");
            object itemType = itemTyoeProperty.GetValue(itemInfo);
            Console.WriteLine(itemType.ToString());

            //修改属性值
            itemInfo.ItemName = "工资发放";//直接代码修改
            //type.GetProperty("ItemName").SetValue(itemInfo, "朋友还钱");//通过反射修改
            Console.WriteLine("===============================================");
            foreach (PropertyInfo property in properties)
            {
                Console.WriteLine(property.Name + ":" + property.GetValue(itemInfo).ToString());
                //property.Name获取属性的名称，property.GetValue(obj)获取obj对象中property属性的值
            }


            //2.字段
            //公有字段
            var fields = type.GetFields();//字段的多个获取方式
            FieldInfo fRemark = type.GetField("remark");//指定名称的字段
            string remark = fRemark.GetValue(itemInfo).ToString();//获取字段的值
            FieldInfo fType = type.GetField("itemType", BindingFlags.NonPublic | BindingFlags.Instance);//指定名称的字段


            //3.方法
            string strInfo = itemInfo.GetItemInfo(); //直接调用

            //通过反射调用方法
            MethodInfo[] method = type.GetMethods();
            //获取指定的方法
            MethodInfo methodInfo = type.GetMethod("GetItemInfo");
            //调用方法 无参方法 没有参数 必须要写null
            string reStr = methodInfo.Invoke(itemInfo, null).ToString();

            //获取带一个参数的方法
            MethodInfo setCount = type.GetMethod("SetCount", new Type[] { typeof(int) });
            //调用带一个参数的方法
            setCount.Invoke(itemInfo, new object[] { 100 });



            //动态加载程序集
            Assembly assModels = null;
            //1) Load  传入程序集文件名，不带.dll后缀名  dll文件放入起始位置  .Net8 识别不到程序
            //Models项目添加引用进来，这种方式就可以
            //assModels = Assembly.Load("GJB.Models");//这种不行
            //2) LoadFile 传入程序集文件的完整路径（绝对路径）
            assModels = Assembly.LoadFile("F:\\Study\\朝夕教育视频课程\\WPFLesson\\ReflectionDemo\\bin\\Debug\\net8.0\\GJB.Models.dll");
            //3)LoadFrom(程序集文件名,带.dll后缀名)
            //assModels = Assembly.LoadFrom("GJB.Models.dll");





            Type stuType = assModels.GetType("GJB.Models.Student");//获取类型

            //Student stu = (Student)Activator.CreateInstance(stuType);//创建对象




            //反射与泛型结合应用
            ModelBase<ItemInfo> baseItem = new ModelBase<ItemInfo>();
            baseItem.Add(new ItemInfo() { Id = 101, ItemType = "收入", ItemName = "银行转账" });
            baseItem.Add(new ItemInfo() { Id = 102, ItemType = "支出", ItemName = "买菜" });
            var itemList = baseItem.GetList();
            foreach (var item in itemList)
            {
                Console.WriteLine(baseItem.GetInfo(item));
            }
            
            

            Console.ReadKey();
        }
    }
}
